package co.fitstart.coach.web.controller.courseware;

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.demo2do.core.BusinessException;
import com.demo2do.core.persistence.GenericDaoSupport;
import com.demo2do.core.support.Result;
import com.demo2do.core.utils.CollectionUtils;
import com.demo2do.core.utils.JsonUtils;

import co.fitstart.coach.entity.courseware.DietaryRequest;
import co.fitstart.coach.entity.courseware.PlannedScheduleRequest;
import co.fitstart.coach.entity.security.Login;
import co.fitstart.coach.service.CourseService;
import co.fitstart.coach.service.CoursewareService;
import co.fitstart.coach.service.PrincipalService;
import co.fitstart.coach.service.WeeklyPlanService;
import co.fitstart.coach.web.resolver.Secure;
import co.fitstart.entity.course.round.CourseRound;
import co.fitstart.entity.courseware.dietary.Dietary;
import co.fitstart.entity.courseware.dietary.DietaryProgramTemplate;
import co.fitstart.entity.courseware.exercise.Exercise;
import co.fitstart.entity.courseware.exercise.LissType;
import co.fitstart.entity.courseware.exercise.PlannedSchedule;
import co.fitstart.entity.courseware.fitnessgroup.BatchCourseware;
import co.fitstart.entity.courseware.fitnessgroup.BatchCoursewareType;
import co.fitstart.entity.principal.Principal;

/**
 * 周计划
 * @author haiyan_xiao
 *
 */
@Controller
@RequestMapping("/rounds")
public class WeeklyPlanController {
    private static final Logger logger = LoggerFactory.getLogger(WeeklyPlanController.class);
    
    @Autowired
    private PrincipalService principalService;
    
    @Autowired
    private CourseService courseService;
    
    @Autowired
    private CoursewareService coursewareService;
    
    @Autowired
    private WeeklyPlanService weeklyPlanService;
    
    @Autowired
    private GenericDaoSupport genericDaoSupport;
    
    /*@RequestMapping(value = "/{courseRoundId}/weekly-plans", method = RequestMethod.GET)
    public ModelAndView weeklyPlans(@Secure Login login,
                                    @PathVariable("courseRoundId") Long courseRoundId) {
        ModelAndView modelAndView = new ModelAndView("courseware/batch/weekly-plan-list");
        
        Principal coach = principalService.load(Principal.class, login.getId());
        CourseRound courseRound = courseService.loadCourseRound(courseRoundId);
        
        if(courseRound != null && !courseRound.isDisabled() && courseRound.getCoach() == coach) {
            BatchCourseware batchCourseware = null;
            if(week == null) {
                batchCourseware = coursewareService.getBatchCourseware(courseRound, BatchCoursewareType.WEEKLY);
            } else {
                batchCourseware = coursewareService.getBatchCourseware(courseRound, BatchCoursewareType.WEEKLY, week);
            }
            
            if(batchCourseware != null) {
                Dietary dietary = weeklyPlanService.generallyLoadDietary(batchCourseware);
                
                modelAndView.addObject("batchId", batchCourseware.getId());
                modelAndView.addObject("generated", batchCourseware.getEditStatus().isGenerated());
                modelAndView.addObject("dietary", dietary);
                modelAndView.addObject("week", batchCourseware.getSorting());
                modelAndView.addObject("maxWeek", courseRound.getFitnessGroup().getWeeks());
            }

            modelAndView.addObject("courseRoundId", courseRoundId);
        }
        
        return modelAndView;
    }*/
    
    /**
     * 周计划饮食
     * @param login
     * @param courseRoundId
     * @return
     */
    @RequestMapping(value = "/{courseRoundId}/weekly-plan", method = RequestMethod.GET)
    public ModelAndView target(@Secure Login login,
                               @PathVariable("courseRoundId") Long courseRoundId,
                               @RequestParam(value = "week", required = false) Integer week,
                               @RequestParam(value = "scheduleId", required = false) Long scheduleId,
                               @RequestParam(value = "back", required = false) String back) {
        ModelAndView modelAndView = new ModelAndView("courseware/batch/weekly-plan-dietary");
        
        Principal coach = principalService.load(Principal.class, login.getId());
        CourseRound courseRound = courseService.loadCourseRound(courseRoundId);
        
        if(courseRound != null) {
            if(week == null) {
                week = weeklyPlanService.getCurrentWeek(courseRound);
            }
            
            BatchCourseware batchCourseware = coursewareService.getBatchCourseware(courseRound, BatchCoursewareType.WEEKLY, week);
            
            if(batchCourseware != null) {
                Dietary dietary = weeklyPlanService.generallyLoadDietary(batchCourseware);
                
                modelAndView.addObject("batchId", batchCourseware.getId());
                modelAndView.addObject("generated", batchCourseware.getEditStatus().isGenerated());
                modelAndView.addObject("dietary", dietary);
                modelAndView.addObject("week", batchCourseware.getSorting());
                modelAndView.addObject("maxWeek", courseRound.getFitnessGroup().getWeeks());
            }

            modelAndView.addObject("courseRound", courseRound);
            modelAndView.addObject("edit", courseRound.getCoach() == coach);
            
            Map<String, Date> map = weeklyPlanService.getWeekBeginAndEnd(courseRound, week);
            
            modelAndView.addObject("begin", map.get("begin"));
            modelAndView.addObject("end", map.get("end"));
            modelAndView.addObject("scheduleId", scheduleId);
        }
        
        modelAndView.addObject("back", back);
        
        return modelAndView;
    }
    
    /**
     * 
     * @param login
     * @param courseRoundId
     * @param batchId
     * @return
     */
    @RequestMapping(value = "/{courseRoundId}/weekly-plan/{batchId}/edit-dietary", method = RequestMethod.GET)
    public ModelAndView editDietary(@Secure Login login,
                                    @PathVariable("courseRoundId") Long courseRoundId,
                                    @PathVariable("batchId") Long batchId,
                                    @RequestParam(value="scheduleId", required = false) Long scheduleId,
                                    @RequestParam(value = "back", required = false) String back) {
        ModelAndView modelAndView = new ModelAndView("courseware/batch/weekly-plan-dietary-edit");
        
        Principal coach = principalService.load(Principal.class, login.getId());
        BatchCourseware batchCourseware = genericDaoSupport.load(BatchCourseware.class, batchId);
        
        if(batchCourseware != null && !batchCourseware.isDisabled() && batchCourseware.getType().isWeekly()
                && batchCourseware.getCourseRound().getCoach() == coach) {
            
            Dietary dietary = weeklyPlanService.generallyLoadDietary(batchCourseware);
            Map<String, List<DietaryProgramTemplate>> diets = coursewareService.listDietaryProgramTemplate();

            modelAndView.addObject("courseRoundId", courseRoundId);
            modelAndView.addObject("batchId", batchId);
            modelAndView.addObject("week", batchCourseware.getSorting());
            modelAndView.addObject("dietary", dietary);
            modelAndView.addObject("breakfasts", JsonUtils.toJsonString(diets.get("breakfast")));
            modelAndView.addObject("lunchs", JsonUtils.toJsonString(diets.get("lunch")));
            modelAndView.addObject("dinners", JsonUtils.toJsonString(diets.get("dinner")));
            modelAndView.addObject("snacks", JsonUtils.toJsonString(diets.get("snack")));
            modelAndView.addObject("scheduleId", scheduleId);
        }
        
        modelAndView.addObject("back", back);
        
        return modelAndView;
    }
    
    /**
     * 
     * @param login
     * @param courseRoundId
     * @param templateId
     * @return
     */
    @RequestMapping(value = "/dietary-template/{templateId}/description", method = RequestMethod.POST)
    public @ResponseBody String templateDescription(@Secure Login login,
                                                    @PathVariable("templateId") Long templateId) {
        
        Result result = new Result();
        
        try {
            DietaryProgramTemplate template = genericDaoSupport.load(DietaryProgramTemplate.class, templateId);
            
            if(template != null) {
                result.success().message("获取成功!").data("description", template.getDescription());
                
            } else {
                result.fail().message("获取失败!");
            }
        } catch (Exception e) {
            
            logger.error("WeeklyPlanController#templateDescription() error - ", e);
            
            result.fail().message("获取失败!");
            
        }
        
        return JsonUtils.toJsonString(result);
    }
    
    /**
     * 
     * @param login
     * @param courseRoundId
     * @param batchId
     * @param dietary
     * @return
     */
    @RequestMapping(value = "/{courseRoundId}/weekly-plan/{batchId}/edit-dietary", method = RequestMethod.PATCH)
    public @ResponseBody String onEditDietary(@Secure Login login,
                                              @PathVariable("courseRoundId") Long courseRoundId,
                                              @PathVariable("batchId") Long batchId,
                                              DietaryRequest dietary) {
        
        Result result = new Result();
        
        try {
            Principal coach = principalService.load(Principal.class, login.getId());
            BatchCourseware batchCourseware = genericDaoSupport.load(BatchCourseware.class, batchId);
            
            if(batchCourseware != null && !batchCourseware.isDisabled() && batchCourseware.getType().isWeekly()
                    && batchCourseware.getCourseRound().getCoach() == coach) {
                weeklyPlanService.editDietary(batchCourseware, dietary);
                
                result.success().message("修改饮食计划成功!");
                
            } else {
                result.fail().message("修改饮食计划失败!");
            }
        } catch (Exception e) {
            
            logger.error("WeeklyPlanController#onEditDietary() error - ", e);
            
            result.fail().message("修改饮食计划失败!");
            
        }
        
        return JsonUtils.toJsonString(result);
    }
    
    /**
     * 
     * @param login
     * @param courseRoundId
     * @param week
     * @return
     */
    @RequestMapping(value = "/{courseRoundId}/weekly-plan/exercise", method = RequestMethod.GET)
    public ModelAndView exercise(@Secure Login login,
                                 @PathVariable("courseRoundId") Long courseRoundId,
                                 @RequestParam(value = "week", required = false) Integer week,
                                 @RequestParam(value="scheduleId", required = false) Long scheduleId,
                                 @RequestParam(value = "back", required = false) String back) {
        ModelAndView modelAndView = new ModelAndView("courseware/batch/weekly-plan-exercise");
        
        Principal coach = principalService.load(Principal.class, login.getId());
        CourseRound courseRound = courseService.loadCourseRound(courseRoundId);
        
        if(courseRound != null) {
            if(week == null) {
                week = weeklyPlanService.getCurrentWeek(courseRound);
            }
            
            BatchCourseware batchCourseware = coursewareService.getBatchCourseware(courseRound, BatchCoursewareType.WEEKLY, week);
            
            if(batchCourseware != null) {
                Exercise exercise = weeklyPlanService.loadExercise(batchCourseware);
                List<PlannedSchedule> schedules = weeklyPlanService.listPlannedSchedule(batchCourseware);
                
                modelAndView.addObject("batchId", batchCourseware.getId());
                modelAndView.addObject("generated", batchCourseware.getEditStatus().isGenerated());
                modelAndView.addObject("exercise", exercise);
                modelAndView.addObject("schedules", CollectionUtils.constructMapValueFromList(schedules, "day"));
                modelAndView.addObject("courseSchedules", weeklyPlanService.listSchedule(batchCourseware, schedules));
            }

            modelAndView.addObject("courseRound", courseRound);
            modelAndView.addObject("week", week);
            modelAndView.addObject("maxWeek", courseRound.getFitnessGroup().getWeeks());
            modelAndView.addObject("edit", courseRound.getCoach() == coach);
            
            Map<String, Date> map = weeklyPlanService.getWeekBeginAndEnd(courseRound, week);
            
            modelAndView.addObject("begin", map.get("begin"));
            modelAndView.addObject("end", map.get("end"));
            modelAndView.addObject("scheduleId", scheduleId);
        }
        
        modelAndView.addObject("back", back);
        
        return modelAndView;
    }
    
    @RequestMapping(value = "/{courseRoundId}/weekly-plan/{batchId}/edit-exercise", method = RequestMethod.GET)
    public ModelAndView editExercise(@Secure Login login,
                                     @PathVariable("courseRoundId") Long courseRoundId,
                                     @PathVariable("batchId") Long batchId,
                                     @RequestParam(value="scheduleId", required = false) Long scheduleId,
                                     @RequestParam(value = "back", required = false) String back) {
        ModelAndView modelAndView = new ModelAndView("courseware/batch/weekly-plan-exercise-edit");
        
        Principal coach = principalService.load(Principal.class, login.getId());
        BatchCourseware batchCourseware = genericDaoSupport.load(BatchCourseware.class, batchId);
        
        if(batchCourseware != null && !batchCourseware.isDisabled()
                && batchCourseware.getCourseRound().getCoach() == coach) {
            Exercise exercise = weeklyPlanService.loadExercise(batchCourseware);
            List<PlannedSchedule> schedules = weeklyPlanService.listPlannedSchedule(batchCourseware);
            
            modelAndView.addObject("batchId", batchCourseware.getId());
            modelAndView.addObject("exercise", exercise);
            modelAndView.addObject("schedules", CollectionUtils.constructMapValueFromList(schedules, "day"));

            modelAndView.addObject("courseRoundId", courseRoundId);
            modelAndView.addObject("week", batchCourseware.getSorting());
            modelAndView.addObject("batchId", batchId);
            modelAndView.addObject("scheduleId", scheduleId);
        }
        
        modelAndView.addObject("back", back);
        
        return modelAndView;
    }
    
    @RequestMapping(value = "/{courseRoundId}/weekly-plan/{batchId}/edit-exercise", method = RequestMethod.PATCH)
    public @ResponseBody String onEditExercise(@Secure Login login,
                                               @PathVariable("courseRoundId") Long courseRoundId,
                                               @PathVariable("batchId") Long batchId,
                                               Exercise exercise,
                                               PlannedScheduleRequest plannedSchedules,
                                               @RequestParam(value = "lissTypes", required = false) List<LissType> lissTypes) {
        
        Result result = new Result();
        
        try {
            Principal coach = principalService.load(Principal.class, login.getId());
            BatchCourseware batchCourseware = genericDaoSupport.load(BatchCourseware.class, batchId);
            
            if(batchCourseware != null && !batchCourseware.isDisabled() && batchCourseware.getType().isWeekly()
                    && batchCourseware.getCourseRound().getCoach() == coach) {
                weeklyPlanService.editExercise(batchCourseware, exercise, plannedSchedules, lissTypes);
                
                result.success().message("修改运动计划成功!");
                
            } else {
                result.fail().message("修改运动计划失败!");
            }
        } catch (Exception e) {
            
            logger.error("WeeklyPlanController#onEditExercise() error - ", e);
            
            result.fail().message("修改运动计划失败!");
            
        }
        
        return JsonUtils.toJsonString(result);
    }
    
    @RequestMapping(value = "/{courseRoundId}/weekly-plan/{batchId}/link", method = RequestMethod.PATCH)
    public @ResponseBody String link(@Secure Login login,
                                     @PathVariable("courseRoundId") Long courseRoundId,
                                     @PathVariable("batchId") Long batchId,
                                     @RequestParam(name = "coachTips", required = false) String coachTips) {
        
        Result result = new Result();
        
        try {
            Principal coach = principalService.load(Principal.class, login.getId());
            BatchCourseware batchCourseware = genericDaoSupport.load(BatchCourseware.class, batchId);
            
            if(batchCourseware != null && !batchCourseware.isDisabled() && batchCourseware.getType().isWeekly()
                    && batchCourseware.getCourseRound().getCoach() == coach) {
                weeklyPlanService.linkWeeklyPlan(batchCourseware, coachTips);
                
                result.success().message("发送第" + batchCourseware.getSorting() + "周课件成功!");
                
            } else {
                result.fail().message("发送课件失败!");
            }
        } catch (BusinessException e) {
            result.fail().message(e.getMessage());
        } catch (Exception e) {
            
            logger.error("WeeklyPlanController#link() error - ", e);
            
            result.fail().message("发送课件失败!");
            
        }
        
        return JsonUtils.toJsonString(result);
    }
}
